#include "HttpRequest.h"

#include <QEventLoop>
#include <QJsonObject>
#include <QJsonParseError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QByteArray>
#include <QNetworkReply>
#include <QJsonArray>
#include <QFile>
#include <QFileInfo>
#include <QHttpPart>
#include <QUrlQuery>
#include <QRegularExpression>
#include <QNetworkReply>
#include <QTextCodec>
#include <QTimer>
#include "MyJson.h"

QString HttpRequest::m_requestHeader = "127.0.0.1:5000";
QVariantMap HttpRequest::m_map_post;
QVariantMap HttpRequest::m_map_get;


QVariantMap HttpRequest::getMap_post()
{
    return m_map_post;
}

void HttpRequest::setMap_post(const QVariantMap &map_post)
{
    m_map_post = map_post;
}

QVariantMap HttpRequest::getMap_get()
{
    return m_map_get;
}

void HttpRequest::setMap_get(const QVariantMap &map_get)
{
    m_map_get = map_get;
}

HttpRequest::HttpRequest(QObject *parent, const QString requestHeader)
    : QObject(parent)
{
    setRequestHeader(requestHeader);
}

HttpRequest::~HttpRequest()
{

}

bool HttpRequest::isValidIPv4(const QString &ipAddress)
{
    // 定义 IPv4 地址的正则表达式
    QRegExp ipRegex("^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$");

    // 使用正则表达式验证 IP 地址
    return ipRegex.exactMatch(ipAddress);
}

int HttpRequest::NormalGetRequest(const QString &path, const QMap<QString, QString> &keyValuePairs)
{
    // 清理get
    m_map_get.clear();

//    if (!isUrlValid(m_requestHeader)) {
//        HttpUrlCheckDialog url_dialog;
//        if (url_dialog.exec() != QDialog::Accepted) {
//            qDebug() << "网络异常退出";
//            return 404;
//        }
//        emit updateIpPort();
//    }

    //生成对应的网络请求
    QString fullRequest = "http://" + m_requestHeader + path;
    if (!keyValuePairs.isEmpty()) {
        fullRequest += "?";
        QStringList parameters;
        for (const QString &paramer : keyValuePairs.keys()) {
            parameters << paramer + "=" + keyValuePairs.value(paramer);
        }
        fullRequest += parameters.join("&");
    }

    qDebug() << fullRequest;

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QNetworkRequest request;
    request.setUrl(QUrl(fullRequest));

    QNetworkReply *reply = manager->get(request);
    QEventLoop eventLoop;
    connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "GET Reply Error:" << reply->errorString();
        QNetworkReply::NetworkError error = reply->error();
        delete manager;
        delete reply;
        return error;
    }

    QByteArray replyData = reply->readAll();
    delete reply;
    delete manager;

    QJsonParseError json_error;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(replyData, &json_error);
    if (json_error.error != QJsonParseError::NoError) {
        qDebug() << "replyData : " << replyData;
        qDebug() << "GET Json Error:" << json_error.errorString();
        return -1;
    }

    QJsonObject rootObj = jsonDoc.object();
    m_map_get = jsonDoc.toVariant().toMap();

    quint8 code = rootObj.value("code").toInt();
    if (code == 200) {
        qDebug() << "code:" << code;
//        if (rootObj.contains("data")) {
//            if (getJsonDatas(rootObj, "")) {
//                qDebug() << "GET成功";
//            } else {
//                qDebug() << "GET失败";
//            }
//        }
        return 0;
    } else {
        return code;
    }
}


int HttpRequest::NormalPostRequest(const QString &path, const QMap<QString, QString> &keyValuePairs)
{
    // 清理post
    m_map_post.clear();

//    if (!isUrlValid(m_requestHeader)) {
//        HttpUrlCheckDialog url_dialog;
//        if (url_dialog.exec() != QDialog::Accepted) {
//            qDebug() << "网络异常退出";
//            return 404;
//        }
//        emit updateIpPort();
//    }

    //生成对应的网络请求
    QNetworkRequest request;
    QString fullRequest = "http://" + m_requestHeader + path;
    // 路径
    m_url = fullRequest;

    request.setUrl(QUrl(m_url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    // 构建POST数据
    QUrlQuery postData;

    // 不为空
    if (!keyValuePairs.isEmpty()) {
        // 添加请求体
        for (const QString &value : keyValuePairs.keys()) {
            postData.addQueryItem(value, keyValuePairs.value(value));
        }
    }

    qDebug() << m_url;
    qDebug() << "postData:" << postData.toString(QUrl::FullyEncoded).toUtf8();


    //发送请求
    QScopedPointer<QNetworkAccessManager> manager(new QNetworkAccessManager);
    QScopedPointer<QNetworkReply> reply(manager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8()));

    QEventLoop eventLoop;
    QObject::connect(reply.data(), SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec();

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "POST Reply Error:" << reply->errorString();
        QNetworkReply::NetworkError error = reply->error();
        return error;
    }

    //解析返回的Json结果
    QByteArray replyData = reply->readAll();
    QJsonParseError json_error;
    QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
    if (json_error.error != QJsonParseError::NoError) {
        qDebug() << "POST Json Error:" << json_error.errorString();
        return -1;
    }

    // Json对象
    QJsonObject rootObj = jsonDoc.object();
    m_map_post = jsonDoc.toVariant().toMap();

    quint8 code = rootObj.value("code").toInt();

    if (code == 200) {
        qDebug() << "code:" << code;
//        if (getJsonDatas(rootObj, "")) {
//            // 成功
//            qDebug() << "POST成功";
//        } else {
//            // 失败
//            qDebug() << "POST失败";
//        }
    }

    return code;
}

void HttpRequest::do_RequestFinished()
{
    // 处理响应
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    if (reply) {
        if (reply->error() == QNetworkReply::NoError) {
            // 读取并处理响应数据
            QByteArray data = reply->readAll();
            // ...
        } else {
            // 处理错误
            qDebug() << "Error: " << reply->errorString();
        }

        // 清理资源
        reply->deleteLater();
    }
}

bool HttpRequest::isUrlValid(const QString &url)
{
    QNetworkAccessManager manager;
    QNetworkRequest request("http://" + url);
    QNetworkReply *reply = manager.head(request);

    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    bool isValid = (reply->error() == QNetworkReply::NoError);
    reply->deleteLater();

    qDebug() << "URL:" << url << " : " << isValid;

    return isValid;
}

QString HttpRequest::requestHeader()
{
    return m_requestHeader;
}

QJsonObject HttpRequest::parseJson(const QString &jsonString) {
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        qWarning() << "JSON parse error: " << parseError.errorString();
        return QJsonObject();
    }

    return jsonDoc.object();
}

void HttpRequest::setRequestHeader(const QString &requestHeader)
{
    m_requestHeader = requestHeader;
//    ConfiguringIniFile::setCurrentIP(m_requestHeader);
}

bool HttpRequest::isValidIpPortFormat(const QString &ipPortString) {
//    QRegularExpression regex("^\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}:[0-9]{1,5}\\b$");

    // 设置正则表达式，只允许输入 IP 地址或域名加端口号的格式
    QRegularExpression regex("^((\\d{1,3}\\.){3}\\d{1,3}:\\d{1,5})|([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}(\\:\\d{1,5})?)$");
    QRegularExpressionMatch match = regex.match(ipPortString);

    return match.hasMatch();
}


bool HttpRequest::GetCsvUploadInfo(const QString &path, const QString &filePath)
{
    QString fullRequest = "http://" + m_requestHeader + path;
    qDebug() << fullRequest;

    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QNetworkRequest request;
    request.setUrl(QUrl(fullRequest));

    QNetworkReply *reply = manager->get(request);
    QEventLoop eventLoop;
    connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();

    bool success = false;

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "GET Reply Error:" << reply->errorString();
        QNetworkReply::NetworkError error = reply->error();
        delete reply;
        delete manager;
        return false; // 确保函数返回 false 而不是 error，表示请求失败
    }

    QByteArray replyData = reply->readAll();
    delete reply;
    delete manager;

    QJsonParseError json_error;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(replyData, &json_error);
    if (json_error.error != QJsonParseError::NoError) {
        qDebug() << "replyData : " << replyData;
        qDebug() << "GET Json Error:" << json_error.errorString();
        return false; // 确保函数返回 false 而不是 -1，表示解析失败
    }

    QJsonObject rootObj = jsonDoc.object();
    m_map_get = jsonDoc.toVariant().toMap();

    quint8 code = rootObj.value("code").toInt();
    qDebug() << "code:" << code;
    if (code == 200) {
        if (false == readCsvJson(jsonDoc)) {
            qDebug() << "读取文件内容失败...";
            return false; // 确保函数返回 false 表示读取文件内容失败
        }

        QString content = m_map_get.value("data").toString();

        qDebug() << content;

        QJsonObject obj = parseJson(content);

        qDebug() << "获取到产品码："  << obj.value("productUniqueCode").toString();

        m_map_get.insert("productUniqueCode", obj.value("productUniqueCode").toString());

//        // 将内容转换为 GB2312 编码
//        QTextCodec *codec = QTextCodec::codecForName("GB2312");
//        QByteArray gb2312Bytes = codec->fromUnicode(content); // 转换为 GB2312 编码的 QByteArray
//        // Base64解码
//        QByteArray base64Data = QByteArray::fromBase64(gb2312Bytes);

//        // 进行UTF-8转码
//        QString CsvTextData = QString::fromUtf8(base64Data);
////        qDebug() << "CsvTextData:" << CsvTextData;
//        m_map_get.insert("file_UTF8", CsvTextData);

//        // 进行GB2312转码
//        QTextCodec *codec_GBK = QTextCodec::codecForName("GBK");
//        if (codec_GBK) {
//            CsvTextData = codec_GBK->toUnicode(base64Data);
////            qDebug() << "Decoded String with GBK:" << CsvTextData;
//            m_map_get.insert("file_GBK", CsvTextData);

//        }
        success = true;
    } else {
        qDebug() << "GET 请求返回错误代码:" << code;
        success = false;
    }

    return success;
}

#if 0

bool HttpRequest::PostCsvUploadInfo(const QString &path, const QString &filePath)
{
    // 生成对应的网络请求
    QNetworkRequest request;
    QString fullRequest = "http://" + m_requestHeader + path;
    m_url = fullRequest;
    request.setUrl(QUrl(m_url));

    qDebug() << m_url;

    // 创建 QHttpMultiPart 对象
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    // 打开文件并读取内容
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "无法打开文件";
        delete multiPart;
        return false;
    }

    QByteArray fileContent = file.readAll();
    file.close();

    // 对文件内容进行 Base64 编码
    QByteArray base64Content = fileContent.toBase64();

    // 创建文件部分
    QHttpPart filePart;
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"" + QFileInfo(filePath).fileName() + "\""));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    filePart.setBody(base64Content);

    // 将文件部分添加到 multiPart
    multiPart->append(filePart);

    // 发送请求
    QScopedPointer<QNetworkAccessManager> manager(new QNetworkAccessManager);
    QScopedPointer<QNetworkReply> reply(manager->post(request, multiPart));
    multiPart->setParent(reply.data()); // 让 reply 管理 multiPart 对象的内存

    QEventLoop eventLoop;
    QTimer timeoutTimer;
    timeoutTimer.setSingleShot(true);

    // 连接 timeout 信号和槽，处理超时
    QObject::connect(&timeoutTimer, &QTimer::timeout, &eventLoop, [&]() {
        qDebug() << "Request timed out";
        reply->abort();
    });

    // 连接 reply 完成信号到事件循环的 quit 槽
    QObject::connect(reply.data(), SIGNAL(finished()), &eventLoop, SLOT(quit()));

    // 设置超时时间，例如 5000 毫秒（5 秒）
    timeoutTimer.start(5000);

    // 执行事件循环，等待响应或超时
    eventLoop.exec();

    // 检查请求是否成功完成
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "POST Reply Error:" << reply->errorString();
        QNetworkReply::NetworkError error = reply->error();
        qDebug() << "NetworkError Code:" << error;
        return false;
    }

    // 解析返回的 JSON 结果
    QByteArray replyData = reply->readAll();
    QJsonParseError json_error;
    QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
    if (json_error.error != QJsonParseError::NoError) {
        qDebug() << "POST Json Error:" << json_error.errorString();
        return false;
    }

    // JSON 对象
    QJsonObject rootObj = jsonDoc.object();
    m_map_post = jsonDoc.object().toVariantMap();

    quint8 code = rootObj.value("code").toInt();

    qDebug() << "code:" << code;

    if (200 == code) {
        if(false == readCsvJson(jsonDoc)) {
            qDebug() << "读取文件内容失败...";
        }
    }

    return true;
}

#else
bool HttpRequest::PostCsvUploadInfo(const QString &path, const QString &filePath)
{
    // 获取CSV文件添加到JSON
//    QJsonDocument csvJsonDoc(getCsvJsonObj(filePath));
    QJsonObject obj;

    obj.insert("productUniqueCode", "1232");
    obj.insert("cameraCode", "0");
    obj.insert("cameraStatus", "0");
    obj.insert("takePhotoNum", "1");
    QJsonDocument csvJsonDoc(obj);

    QByteArray jsonByteArray = csvJsonDoc.toJson(QJsonDocument::Compact);

    // 生成对应的网络请求
    QNetworkRequest request;
    QString fullRequest = "http://" + m_requestHeader + path;
    m_url = fullRequest;
    request.setUrl(QUrl(m_url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    qDebug() << m_url;

    // 发送请求
    QScopedPointer<QNetworkAccessManager> manager(new QNetworkAccessManager);
    QScopedPointer<QNetworkReply> reply(manager->post(request, jsonByteArray));

    QEventLoop eventLoop;
    QTimer timeoutTimer;
    timeoutTimer.setSingleShot(true);

    // 连接timeout信号和槽，处理超时
    QObject::connect(&timeoutTimer, &QTimer::timeout, &eventLoop, [&]() {
        qDebug() << "Request timed out";
        reply->abort();
    });

    // 连接reply完成信号到事件循环的quit槽
    QObject::connect(reply.data(), SIGNAL(finished()), &eventLoop, SLOT(quit()));

    // 设置超时时间，例如5000毫秒（5秒）
    timeoutTimer.start(5000);

    // 执行事件循环，等待响应或超时
    eventLoop.exec();

    // 检查请求是否成功完成
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "POST Reply Error:" << reply->errorString();
        QNetworkReply::NetworkError error = reply->error();
        qDebug() << "NetworkError Code:" << error;
        return false;
    }

    // 解析返回的Json结果
    QByteArray replyData = reply->readAll();
    QJsonParseError json_error;
    QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
    if (json_error.error != QJsonParseError::NoError) {
        qDebug() << "POST Json Error:" << json_error.errorString();
        return false;
    }

    // Json对象
    QJsonObject rootObj = jsonDoc.object();
    m_map_post = jsonDoc.object().toVariantMap();

    quint8 code = rootObj.value("code").toInt();

    qDebug() << "code:" << code;

    if (200 == code) {
        if(false == readCsvJson(jsonDoc)) {
            qDebug() << "读取文件内容失败...";
        }
    }

    return true;
}
#endif

void HttpRequest::sendCsvJson(HttpRequest *m_http, QString Path, QString fileName)
{
    m_http->PostCsvUploadInfo(Path,fileName);

    qDebug() << "CODE:" << HttpRequest::m_map_post.value("code").toInt();
    if(200 == HttpRequest::m_map_post.value("code").toInt())
    {
        QString massage = HttpRequest::m_map_post.value("massage").toString();
        QVariantMap CsvMap = HttpRequest::m_map_post.value("data").toMap();

        qDebug() << "MESSAGE:" << massage;
        qDebug() << "DATA:"    << CsvMap;

        QString content = CsvMap.value("file").toString();

        // 将内容转换为 GB2312 编码
        QTextCodec *codec = QTextCodec::codecForName("GB2312");
        if (codec) {
            QByteArray gb2312Bytes = codec->fromUnicode(content); // 转换为 GB2312 编码的 QByteArray
            // 如果你需要将结果保存为字符串（例如，为了显示或进一步处理），可以这样做：
//            qDebug() << "gb2312Bytes:" << gb2312Bytes;
            QString gb2312String = codec->toUnicode(gb2312Bytes); // 通常这不是必要的，除非你需要在 QString 中以 GB2312 编码处理数据
//            qDebug() << "GB2312:" << gb2312String; // 但通常你只需要 QByteArray 就可以写入文件或通过网络发送

            // Base64解码
            QByteArray base64Data = QByteArray::fromBase64(gb2312Bytes);

            // 进行UTF-8转码
            QString CsvTextData = QString::fromUtf8(base64Data);
//            qDebug() << "CsvTextData:" << CsvTextData;

            // 进行GB2312转码
            QTextCodec *codec = QTextCodec::codecForName("GBK");
            if (codec) {
                CsvTextData = codec->toUnicode(base64Data);
//                qDebug() << "Decoded String with GBK:" << CsvTextData;
            }




//            QString text = QString::fromUtf8(content.toUtf8());
//            qDebug() << "text:" << text;

//            // 使用本地编码进行转换
//            QString textLocal = QString::fromLocal8Bit(content.toUtf8());
//            qDebug() << "使用本地编码转换后的 QString:" << textLocal;

//            // 使用 Latin1 编码进行转换
//            QString textLatin1 = QString::fromLatin1(content.toUtf8());
//            qDebug() << "使用 Latin1 编码转换后的 QString:" << textLatin1;

        } else {
            // 处理找不到 GB2312 编码的情况
            qDebug() << "QString:" <<  QString();
        }


    }
}
